<template>
  <div>
    <button @click="toggleTextEcho">标题</button>
    <button @click="toggleLineEcho">线条</button>
    <button @click="toggleClustering">聚合点</button>
    层级：{{ zoomLevel }}
    经度：{{ lngLat.lng }}
    纬度：{{ lngLat.lat }}
    <div id="amap-container" ref="amap" :style="height"></div>
  </div>
</template>

<script>
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import '/static/css/leaflet.icon.pulse.css';
import '/static/css/leaflet.markercluster.css';
import '/static/css/leaflet.markercluster.default.css';
import '/static/css/leaflet.search.css';
import '/static/js/leaflet.icon.pulse.js';
import '/static/js/leaflet.markercluster.js';
import '/static/js/leaflet.migrationLayer.js';
import '/static/js/leaflet.search.js';
import { mapState } from 'vuex';

export default {
  name: 'AMap',
  data() {
    return {
      // 地图
      map: null,
      // 标记点组
      markerGroup: null,
      // 标记点
      markers: null,
      // 线条
      lines: null,
      // 缩放层级
      zoomLevel: 5,
      // 经纬度
      lngLat: {
        lng: 104.2,
        lat: 35.6
      },
      // 容器高度
      height: null,
      // 开关：文本回显
      showTextEcho: false,
      // 开关：线条回显
      showLineEcho: false,
      // 开关：是否聚合
      enableClustering: true,
    };
  },
  computed: {
    ...mapState({
      setting: (state) => state.setting.setting,
    }),
  },
  watch: {
    // 监听调整地图高度
    'setting.showWorkTab': {
      handler(val) {
        let _this = this;
        // 更新容器高度
        _this.updateHeight(val);
      },
      immediate: true,
    },
    // 监听地图层级渲染
    zoomLevel: {
      handler(val) {
        let _this = this;
        // 隐藏/显示线条
        _this.isShowLines(val);
      }
    },
  },
  mounted() {
    let _this = this;
    _this.$nextTick(() => {
      // 初始化地图
      _this.initMap();
    });
  },
  methods: {
    // 切换文本回显开关
    toggleTextEcho() {
      let _this = this;
      _this.showTextEcho = !_this.showTextEcho;
      _this.updateMarkersLines();
    },
    // 切换线条回显开关
    toggleLineEcho() {
      let _this = this;
      _this.showLineEcho = !_this.showLineEcho;
      if (_this.showLineEcho) {
        _this.lines.setOptions({
          pulseRadius: 5,
          pulseBorderWidth: 1,
          arcWidth: 1,
          // 使用开关状态
          arcLabel: _this.showTextEcho,
          arcLabelFont: '10px sans-serif',
        });
        _this.lines.show();
      } else {
        _this.lines.hide();
      }
    },
    // 切换是否聚合开关
    toggleClustering() {
      let _this = this;
      _this.enableClustering = !_this.enableClustering;
      if (_this.markerGroup) {
        _this.map.removeLayer(_this.markerGroup);
        _this.initMarkers();
      }
    },
    // 更新标记点样式
    updateMarkersLines() {
      let _this = this;
      _this.markerGroup.eachLayer(layer => {
        if (layer.setIcon) {
          layer.setIcon(L.icon.pulse({ ...layer.options.icon.options, text: _this.showTextEcho }));
        }
      });
      if (_this.showLineEcho) {
        _this.lines.setOptions({
          pulseRadius: 5,
          pulseBorderWidth: 1,
          arcWidth: 1,
          // 使用开关状态
          arcLabel: _this.showTextEcho,
          arcLabelFont: '10px sans-serif',
        });
      }
    },
    // 计算高度
    updateHeight(val) {
      let _this = this;
      if (val) {
        _this.height = 'height: calc(100vh - 85px);';
      } else {
        _this.height = 'height: calc(100vh - 40px);';
      }
    },
    // 初始化地图
    async initMap() {
      let _this = this;
      // 中心点位
      _this.map = L.map(_this.$refs.amap).setView([35.6, 104.2], 5);
      // 瓦片资源
      let tileLayer = L.tileLayer('/cdn/{z}/{x}/{y}/tile.png', {
        minZoom: 4,
        maxZoom: 14,
      }).addTo(_this.map);
      // 默认瓦片
      const defaultTileImageUrl = '/static/images/default-tile.png';
      tileLayer.on('tileerror', (event) => {
        event.src = defaultTileImageUrl;
        event.tile.src = defaultTileImageUrl;
      });
      // 版权信息
      let attribution = document.getElementsByClassName('leaflet-control-attribution')[0];
      if (attribution) {
        attribution.style.display = 'none';
      }
      // 监听点击
      _this.map.on('click', function (evt) {
        _this.lngLat = evt.latlng;
      });
      // 监听缩放
      _this.map.on('zoomend', _this.handleZoomChange);
      // 覆盖物
      _this.initMarkers();
      _this.initLines();
      _this.isShowLines(_this.map.getZoom());

      // 搜索
      let searchControl = new L.Control.Search({
        layer: _this.markerGroup,
        propertyName: 'title',
        marker: false,
        moveToLocation: function (latlng, title, map) {
          map.setView(latlng, 13);
        },
        filter: function(item, text) {
          let regex = new RegExp(text, 'i');
          return item.feature.properties.title.match(regex);
        }
      });
      _this.map.addControl(searchControl);
      searchControl.on('search:locationfound', function(e) {
        alert(e.layer.options.title);
      });
    },
    // 标记点位绘制
    initMarkers () {
      let _this = this;
      // 自定义Icon
      let pulsingIcon = (color, label) => {
        return L.icon.pulse({
          iconSize: [4, 4],
          color: color,
          fillColor: color,
          heartbeat: 2,
          animate: true,
          // 使用开关状态
          text: _this.showTextEcho,
          label: label
        });
      };
      // 标记点数据
      let markersData = [
        { lng: 95.44921875, lat: 37.50972584293751, label: 'Marker 1', color: '#28af3b' },
        { lng: 95.45921875, lat: 37.51972584293751, label: 'Marker 2', color: '#28af3b' },
        { lng: 95.46921875, lat: 37.52972584293751, label: 'Marker 3', color: '#28af3b' },
        { lng: 95.47921875, lat: 37.53972584293751, label: 'Marker 4', color: '#28af3b' },
        { lng: 95.48921875, lat: 37.54972584293751, label: 'Marker 5', color: '#28af3b' },
        { lng: 95.49921875, lat: 37.55972584293751, label: 'Marker 6', color: '#28af3b' },
        { lng: 95.44921875, lat: 37.56972584293751, label: 'Marker 7', color: '#28af3b' },
        { lng: 109.95117187500001, lat: 31.952162238024975, label: 'Marker 8', color: '#28af3b' },
        { lng: 116.3232421875, lat: 39.740986355883564, label: 'Marker 9', color: '#ed4014' },
        { lng: 118.87207031250001, lat: 31.89621446335144, label: 'MarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMarkMark 10', color: '#ed4014' },
      ];
      // 标记点组
      if (_this.enableClustering) {
        _this.markerGroup = L.markerClusterGroup({
          spiderfyOnMaxZoom: false,
          disableClusteringAtZoom: 13
        });
      } else {
        // 如果不启用聚类，则使用普通的 LayerGroup
        _this.markerGroup = L.layerGroup();
      }
      // 标记点
      _this.markers = markersData.map(data => {
        let marker = L.marker([data.lat, data.lng], {
          icon: pulsingIcon(data.color, data.label),
          title: data.label
          // 监听标记点点击
        }).on('click', () => {
          alert('You clicked on ' + data.label);
        });
        _this.markerGroup.addLayer(marker);
        return marker;
      });
      // 渲染标记点组
      _this.map.addLayer(_this.markerGroup);
    },
    // 线条绘制
    initLines () {
      let _this = this;
      // 曲线数据
      let lineData = [{
        labels: 'Line 1',
        color: '#28af3b',
        from: [109.95117187500001, 31.952162238024975],
        to: [95.44921875, 37.50972584293751]
      }, {
        labels: 'Line 2',
        color: '#ed4014',
        from: [116.3232421875, 39.740986355883564],
        to: [118.87207031250001, 31.89621446335144]
      }];
      // 脉冲曲线
      // eslint-disable-next-line new-cap
      _this.lines = new L.migrationLayer({
        map: _this.map,
        data: lineData,
        pulseRadius: 5,
        pulseBorderWidth: 1,
        arcWidth: 1,
        // 使用开关状态
        arcLabel: _this.showTextEcho,
        arcLabelFont: '10px sans-serif',
        beArrow: false,
        bePulse: false
      });
      // 监听曲线点击
      _this.lines.onClick((data) => {
        alert('You clicked on ' + data.labels);
      });
      _this.lines.addTo(_this.map);
    },
    // 根据地图层级判断是否显示线条
    isShowLines (level) {
      let _this = this;
      if (level > 12) {
        _this.lines.show();
      } else {
        if (_this.showLineEcho) {
          _this.lines.show();
        } else {
          _this.lines.hide();
        }
      }
    },
    // 地图层级变化
    handleZoomChange() {
      let _this = this;
      _this.zoomLevel = _this.map.getZoom();
      let size = 20 + (_this.zoomLevel - 13) * 2;
      let newSize = [size > 5 ? 6 : size, size > 5 ? 6 : size];
      _this.markerGroup.eachLayer(layer => {
        layer.setIcon(L.icon.pulse({ ...layer.options.icon.options, iconSize: newSize }));
      });
    },
  },
};
</script>

<style lang="scss" scoped>
</style>
